package com.hdw.aopdemo;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.omg.CORBA.ObjectHelper;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAspect implements Ordered{

    /**
     * 定义一个方法, 用于声明切入点表达式. 一般地, 该方法中再不需要添入其他的代码.
     * 使用 @Pointcut 来声明切入点表达式.
     * 后面的其他通知直接使用方法名来引用当前的切入点表达式.
     **/
    @Pointcut("execution(public  * com.hdw.aopdemo.Demo.*())")
    private void log(){};

    @Before("log()")
    private void doBefore(){
        System.out.println("方法执行之前");
    }

    /**
     * 后置最终通知，
     * 在方法返回之后执行
     * 无论有无返回值，无论是正常返回还是异常退出都会执行
     */
    @After("log()")
    private void doAfter(){
        System.out.println("无参方法执行之后");
    }

    @AfterReturning(returning = "object",pointcut = "log()")
    private void doAfterReturn(Object object){
        System.out.println(object.toString());
    }

    /**
     * 环绕通知
     * 在方法返回之前执行
     * 通过proceed()可以控制是否执行被代理的方法
     * 可以强制修改返回信息
     * @param pjd
     * @return
     */
    @Around("log()")
    private Object arround(ProceedingJoinPoint pjd){
        System.out.println("环绕方法执行开始");
        try {
            Object o = pjd.proceed();
            System.out.println("环绕方法执行完成");
            return o;
        }catch (Throwable e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 重写Ordered接口的个体Order方法，用于指定切面的优先级
     * 返回数字越小，优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
